home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 2: CDPD 1 / Almathera Ten on Ten - Disc 2: CDPD 1.iso / pd / 076-100 / 092 / shar / fgetline.c < prev    next >
C/C++ Source or Header  |  1995-03-13  |  4KB  |  125 lines

  1. /* Fgetline.c
  2.  
  3.    Copyright (c) by Fabbian G. Dufoe, III
  4.    All rights reserved.
  5.  
  6.    Permission is granted to redistribute this program provided the source
  7.    code is included in the distribution and this copyright notice is
  8.    unchanged.
  9.  
  10. */
  11.  
  12.  
  13. #include <stdio.h>
  14. #ifdef AMIGA
  15. #include <error.h>
  16. #include <exec/types.h>
  17. #else
  18. #include <errno.h>
  19. #include <ctype.h>
  20. extern int sys_nerr;
  21. extern char *sys_errlist[];
  22. #endif
  23.  
  24.  
  25. #define AVGLINE 512
  26.    /* This is the amount of space which will be allocated initially for
  27.       the buffer into which lines read from the file will be placed. */
  28. #define MARGIN 10
  29.    /* When we get within MARGIN characters of the end of the buffer we
  30.       will try to get more memory before proceeding. */
  31.  
  32.  
  33. char *
  34. fgetline(ifile)
  35.    /* This function gets the next line of text from a file.  The calling
  36.       program passes it a FILE pointer to identify the file.  Fgetline()
  37.       returns a pointer to a null-terminated character string containing the
  38.       line from that file if it successfully read any characters.  It
  39.       returns a NULL pointer if an error occurs or if it encountered end of
  40.       file.  The calling program must examine the external variable errno
  41.       to determine which is the case.  If fgetline() encountered end of file
  42.       errno will be zero. */
  43. FILE *ifile;
  44.    /* This is a file pointer for the file to be read. */
  45. {
  46.    int c;
  47.       /* This is the character read from the file. */
  48.    extern int errno;
  49.       /* This global variable is used to communicate error codes. */
  50.    int i;
  51.       /* This is a counter that is incremented for each character placed
  52.          in the buffer. */
  53.    static int length = AVGLINE;
  54.       /* This is the length of the character buffer that has been
  55.          allocated. */
  56.    static char *line = NULL;
  57.       /* This is the address of the character string containing the line
  58.          read from the file. */
  59.    char *newline;
  60.       /* This is a temporary pointer used when more memory has to be
  61.          allocated.  Realloc() returns a NULL pointer if it fails and we
  62.          don't want to lose track of the characters we have already
  63.          collected. */
  64.  
  65.  
  66.    if (line == NULL)
  67.       /* If the line buffer hasn't been allocated yet do it now. */
  68.       if ((line = (char *)malloc(length)) == NULL)
  69.          /* If malloc() returns a NULL pointer the memory couldn't be
  70.             allocated.  Return a NULL pointer.  The calling program
  71.             can look at errno for the reason. */
  72.          return(NULL);
  73.  
  74.    for (i = 0; (c = fgetc(ifile)) != EOF && c != '\n'; i++)
  75.       /* As long as we don't hit EOF or a newline keep collecting
  76.          characters. */
  77.    {
  78.       *(line + i) = c;
  79.       if (i > length - MARGIN)
  80.          /* If we are within MARGIN characters of the end of the
  81.             buffer try to allocate more memory. */
  82.       {
  83.          newline = (char *)realloc(line, length + AVGLINE);
  84.          if (newline == NULL)
  85.             /* If realloc() failed we try to salvage what we have
  86.                already collected. */
  87.          {
  88.             *(line + ++i) = '\0';
  89.                /* Tack on a null-terminator. */
  90.             return(line);
  91.                /* Return the pointer to the string we have
  92.                   collected so far. */
  93.          }
  94.          length += AVGLINE;
  95.             /* The buffer is longer now, so we'll update our record
  96.                of its length. */
  97.          line = newline;
  98.             /* We got the additional space we asked for so we change
  99.                the pointer to refer to the new buffer. */
  100.       }
  101.    }
  102.  
  103.    if (c == '\n')
  104.       /* If we came to a newline character we are at the end of the
  105.          line.  Add the newline to the end of the buffer. */
  106.       *(line + i++) = c;
  107.  
  108.    if (c == EOF && i == 0)
  109.       /* If we are at end of file and there are no characters in the
  110.          buffer we can free the buffer's memory, set the pointer to
  111.          NULL, and return. */
  112.    {
  113.       free(line);
  114.       line = NULL;
  115.       errno = 0;
  116.       return(NULL);
  117.    }
  118.  
  119.    *(line + i) = '\0';
  120.       /* Terminate the string with a null character. */
  121.  
  122.    return(line);
  123.       /* Return the pointer to the calling program. */
  124. }
  125.